/*
 * bspTimer.c
 *
 *  Created on: 2017年9月20日
 *      Author: Administrator
 */
/* Driver Header files */
#include "bspTimer.h"

tsCbTimer tgTimer;

/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER0_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER0, TIMER_INT_UP))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER0, TIMER_INT_UP);
		if(tgTimer.tvCb0)
			tgTimer.tvCb0(0);
    }
    if(SET == timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_CH0))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH0);
		if(tgTimer.tvCb0)
			tgTimer.tvCb0(timer_channel_capture_value_register_read(TIMER0, TIMER_CH_0));	
    }	
    if(SET == timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_CH1))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH1);
		if(tgTimer.tvCb0)
			tgTimer.tvCb0(timer_channel_capture_value_register_read(TIMER0, TIMER_CH_1));	
    }
	if(SET == timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_CH2))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH2);
		if(tgTimer.tvCb0)
			tgTimer.tvCb0(timer_channel_capture_value_register_read(TIMER0, TIMER_CH_2));	
    }
    if(SET == timer_interrupt_flag_get(TIMER0, TIMER_INT_FLAG_CH3))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER0, TIMER_INT_FLAG_CH3);
		if(tgTimer.tvCb0)
			tgTimer.tvCb0(timer_channel_capture_value_register_read(TIMER0, TIMER_CH_3));	
    }	
}

/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER2_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_UP))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER2, TIMER_INT_UP);
		if(tgTimer.tvCb1)
			tgTimer.tvCb1(0);		
    }
    if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH0))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH0);
		if(tgTimer.tvCb1)
			tgTimer.tvCb1(timer_channel_capture_value_register_read(TIMER2, TIMER_CH_0));	
    }	
    if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH1))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH1);
		if(tgTimer.tvCb1)
			tgTimer.tvCb1(timer_channel_capture_value_register_read(TIMER2, TIMER_CH_1));	
    }
	if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH2))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH2);
		if(tgTimer.tvCb1)
			tgTimer.tvCb1(timer_channel_capture_value_register_read(TIMER2, TIMER_CH_2));	
    }
    if(SET == timer_interrupt_flag_get(TIMER2, TIMER_INT_FLAG_CH3))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER2, TIMER_INT_FLAG_CH3);
		if(tgTimer.tvCb1)
			tgTimer.tvCb1(timer_channel_capture_value_register_read(TIMER2, TIMER_CH_3));	
    }	
}
#if BSP_MCU_TYPE == BSP_MCU_GD32E23x
/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER5_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER5, TIMER_INT_UP))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER5, TIMER_INT_UP);
		if(tgTimer.tvCb2)
			tgTimer.tvCb2(0);		
    }
    if(SET == timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_CH0))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_CH0);
		if(tgTimer.tvCb2)
			tgTimer.tvCb2(timer_channel_capture_value_register_read(TIMER5, TIMER_CH_0));	
    }	
    if(SET == timer_interrupt_flag_get(TIMER5, TIMER_INT_FLAG_CH1))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER5, TIMER_INT_FLAG_CH1);
		if(tgTimer.tvCb2)
			tgTimer.tvCb2(timer_channel_capture_value_register_read(TIMER5, TIMER_CH_1));	
    }
}
#elif BSP_MCU_TYPE == BSP_MCU_GD32F3x0	

/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER1_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_UP))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_UP);
		if(tgTimer.tvCb2)
			tgTimer.tvCb2(0);	
    }
    if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH0))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH0);
		if(tgTimer.tvCb2)
			tgTimer.tvCb2(timer_channel_capture_value_register_read(TIMER1, TIMER_CH_0));	
    }	
    if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH1))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH1);
		if(tgTimer.tvCb2)
			tgTimer.tvCb2(timer_channel_capture_value_register_read(TIMER1, TIMER_CH_1));	
    }
	if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH2))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH2);
		if(tgTimer.tvCb2)
			tgTimer.tvCb2(timer_channel_capture_value_register_read(TIMER1, TIMER_CH_2));	
    }
    if(SET == timer_interrupt_flag_get(TIMER1, TIMER_INT_FLAG_CH3))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER1, TIMER_INT_FLAG_CH3);
		if(tgTimer.tvCb2)
			tgTimer.tvCb2(timer_channel_capture_value_register_read(TIMER1, TIMER_CH_3));	
    }	
}

#endif
/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER13_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER13, TIMER_INT_UP))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER13, TIMER_INT_UP);
		if(tgTimer.tvCb3)
			tgTimer.tvCb3(0);	
    }
    if(SET == timer_interrupt_flag_get(TIMER13, TIMER_INT_FLAG_CH0))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER13, TIMER_INT_FLAG_CH0);
		if(tgTimer.tvCb3)
			tgTimer.tvCb3(timer_channel_capture_value_register_read(TIMER13, TIMER_CH_0));	
    }		
}
/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER14_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER14, TIMER_INT_UP)){
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER14, TIMER_INT_UP);
		if(tgTimer.tvCb4)
			tgTimer.tvCb4(0);	
    }
    if(SET == timer_interrupt_flag_get(TIMER14, TIMER_INT_FLAG_CH0))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER14, TIMER_INT_FLAG_CH0);
		if(tgTimer.tvCb4)
			tgTimer.tvCb4(timer_channel_capture_value_register_read(TIMER14, TIMER_CH_0));	
    }	
    if(SET == timer_interrupt_flag_get(TIMER14, TIMER_INT_FLAG_CH1))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER14, TIMER_INT_FLAG_CH1);
		if(tgTimer.tvCb4)
			tgTimer.tvCb4(timer_channel_capture_value_register_read(TIMER14, TIMER_CH_1));	
    }		
}
/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER15_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER15, TIMER_INT_UP)){
        timer_interrupt_flag_clear(TIMER15, TIMER_INT_UP);
		if(tgTimer.tvCb5)
			tgTimer.tvCb5(0);	
    }
    if(SET == timer_interrupt_flag_get(TIMER15, TIMER_INT_FLAG_CH0))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER15, TIMER_INT_FLAG_CH0);
		if(tgTimer.tvCb5)
			tgTimer.tvCb5(timer_channel_capture_value_register_read(TIMER15, TIMER_CH_0));	
    }	
}
/**
  * @brief  This function handles TIMER2 interrupt request.
  * @param  None
  * @retval None
  */
void TIMER16_IRQHandler(void)
{
    if(SET == timer_interrupt_flag_get(TIMER16, TIMER_INT_UP)){
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER16, TIMER_INT_UP);
		if(tgTimer.tvCb6)
			tgTimer.tvCb6(0);	
    }
    if(SET == timer_interrupt_flag_get(TIMER16, TIMER_INT_FLAG_CH0))
	{
        /* clear channel 0 interrupt bit */
        timer_interrupt_flag_clear(TIMER16, TIMER_INT_FLAG_CH0);
		if(tgTimer.tvCb6)
			tgTimer.tvCb6(timer_channel_capture_value_register_read(TIMER16, TIMER_CH_0));	
    }		
}

/* 定时器初始化
 * freq:频率
 * ptTimerCallback:定时器回调
 * return:NULL
 */
void initTimer(tsCfgTimer *cfg, uint32_t freq, timerCallback ptTimerCb)
{
	timer_parameter_struct timer_initpara;
	double needPeriod,maxPeriod,minPeriod;
	uint16_t prescaler, period;
	
	if(cfg == NULL)
		return;
	

	
	rcu_periph_clock_enable(cfg->timerRcu);	//使能时钟 RCU
#if BSP_MCU_TYPE == BSP_MCU_GD32E23x
	nvic_irq_enable(cfg->nvicIrq,cfg->nvicIrqPriority);//使能更新中断
#elif BSP_MCU_TYPE == BSP_MCU_GD32F3x0	
	nvic_irq_enable(cfg->nvicIrq,cfg->nvicIrqPriority,cfg->nvicIrqSubPriority);//使能更新中断
#endif
	*cfg->tvCb = ptTimerCb;
	
    timer_deinit(cfg->timerPeriph);
	/* 计算频率 */
	needPeriod =  1000000000.0/(double)freq;					//频率转为周期,单位nS
	maxPeriod = 65536.0*(1000000000.0/(double)SystemCoreClock);	//最大可计数周期
	
	prescaler = (uint16_t)(needPeriod/maxPeriod);				//计算预分频,所需周期*最大可计数周期
	minPeriod = 1000000000.0/((double)SystemCoreClock/(double)(prescaler+1));	//分频单次周期时间
	period = needPeriod/minPeriod;
	
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;	//边沿模式
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;	//向上计数
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;	//不分频
    timer_initpara.repetitioncounter = 0U;					//计数重复值0
    timer_initpara.prescaler = prescaler;					//预分频
    timer_initpara.period    = period;						//重装值
    timer_init(cfg->timerPeriph, &timer_initpara);

	timer_interrupt_enable(cfg->timerPeriph, TIMER_INT_UP);
    timer_auto_reload_shadow_enable(cfg->timerPeriph);  
}


/* 捕获初始化
 * freq:频率
 * channel:通道 0~3
 * polarity捕获边沿.
 *		TIMER_IC_POLARITY_RISING
 *		TIMER_IC_POLARITY_FALLING
 *		TIMER_IC_POLARITY_BOTH_EDGE
 * ptTimerCallback:定时器回调
 * return:NULL
 */
void initCapture(tsCfgTimer *cfg, uint32_t channel, uint32_t freq, uint32_t polarity, timerCallback ptTimerCb)
{
	timer_parameter_struct timer_initpara;
	timer_ic_parameter_struct timer_icinitpara;
	uint32_t timerChannel;
	uint32_t interruptSource;
	uint32_t interruptFlag;
	uint32_t prescaler;
	
	if(cfg == NULL)
		return;
	

	rcu_periph_clock_enable(cfg->timerRcu);	//使能时钟 RCU
#if BSP_MCU_TYPE == BSP_MCU_GD32E23x
	nvic_irq_enable(cfg->nvicIrq,cfg->nvicIrqPriority);//使能更新中断
#elif BSP_MCU_TYPE == BSP_MCU_GD32F3x0	
	nvic_irq_enable(cfg->nvicIrq,cfg->nvicIrqPriority,cfg->nvicIrqSubPriority);//使能更新中断
#endif
	*cfg->tvCb = ptTimerCb;
	
    timer_deinit(cfg->timerPeriph);
	
	/* 计算预分频 */				//频率转为周期,单位nS
	prescaler = SystemCoreClock/freq;	//分频单次周期时间
	if(prescaler > 65535u)
		prescaler = 65535u;
    timer_initpara.alignedmode       = TIMER_COUNTER_EDGE;	//边沿模式
    timer_initpara.counterdirection  = TIMER_COUNTER_UP;	//向上计数
    timer_initpara.clockdivision     = TIMER_CKDIV_DIV1;	//不分频
    timer_initpara.repetitioncounter = 0U;					//计数重复值0
    timer_initpara.prescaler = prescaler;					//预分频
    timer_initpara.period    = 65535u;						//重装值
    timer_init(cfg->timerPeriph, &timer_initpara);

	/* 初始化capture */
    timer_channel_input_struct_para_init(&timer_icinitpara);

    timer_icinitpara.icpolarity  = polarity;
    timer_icinitpara.icselection = TIMER_IC_SELECTION_DIRECTTI;
    timer_icinitpara.icprescaler = TIMER_IC_PSC_DIV1;
    timer_icinitpara.icfilter    = 0xa;						//滤波器
	switch(channel)
	{
		case 0:
		{
			timerChannel = TIMER_CH_0;
			interruptSource = TIMER_INT_CH0;
			interruptFlag = TIMER_INT_FLAG_CH0;
		}break;
		
		case 1:
		{
			timerChannel = TIMER_CH_1;
			interruptSource = TIMER_INT_CH1;
			interruptFlag = TIMER_INT_FLAG_CH1;
		}break;	
		
 		case 2:
		{
			timerChannel = TIMER_CH_2;
			interruptSource = TIMER_INT_CH2;
			interruptFlag = TIMER_INT_FLAG_CH2;
		}break;
		
		case 3:
		{
			timerChannel = TIMER_CH_3;
			interruptSource = TIMER_INT_CH3;
			interruptFlag = TIMER_INT_FLAG_CH3;
		}break;		
	}
    timer_input_capture_config(cfg->timerPeriph, timerChannel, &timer_icinitpara);

    /* auto-reload preload enable */
    timer_auto_reload_shadow_enable(cfg->timerPeriph);
	
    /* clear interrupt bit */
    timer_interrupt_flag_clear(cfg->timerPeriph,interruptFlag);
	
    /* interrupt enable */
    timer_interrupt_enable(cfg->timerPeriph,interruptSource);

    /* counter enable */
    timer_enable(cfg->timerPeriph);
	
}


void timerCaptureEn(tsCfgTimer *cfg, uint32_t channel)
{	
	uint32_t timerChannel;
	uint32_t interruptSource;
	uint32_t interruptFlag;	
	switch(channel)
	{
		case 0:
		{
			timerChannel = TIMER_CH_0;
			interruptSource = TIMER_INT_CH0;
			interruptFlag = TIMER_INT_FLAG_CH0;
		}break;
		
		case 1:
		{
			timerChannel = TIMER_CH_1;
			interruptSource = TIMER_INT_CH1;
			interruptFlag = TIMER_INT_FLAG_CH1;
		}break;	
		
 		case 2:
		{
			timerChannel = TIMER_CH_2;
			interruptSource = TIMER_INT_CH2;
			interruptFlag = TIMER_INT_FLAG_CH2;
		}break;
		
		case 3:
		{
			timerChannel = TIMER_CH_3;
			interruptSource = TIMER_INT_CH3;
			interruptFlag = TIMER_INT_FLAG_CH3;
		}break;		
	}
	/* clear interrupt bit */
    timer_interrupt_flag_clear(cfg->timerPeriph,interruptFlag);
	timer_interrupt_enable(cfg->timerPeriph, interruptSource);	
}

void timerCaptureDis(tsCfgTimer *cfg, uint32_t channel)
{
	uint32_t timerChannel;
	uint32_t interruptSource;
	uint32_t interruptFlag;	
	switch(channel)
	{
		case 0:
		{
			timerChannel = TIMER_CH_0;
			interruptSource = TIMER_INT_CH0;
			interruptFlag = TIMER_INT_FLAG_CH0;
		}break;
		
		case 1:
		{
			timerChannel = TIMER_CH_1;
			interruptSource = TIMER_INT_CH1;
			interruptFlag = TIMER_INT_FLAG_CH1;
		}break;	
		
 		case 2:
		{
			timerChannel = TIMER_CH_2;
			interruptSource = TIMER_INT_CH2;
			interruptFlag = TIMER_INT_FLAG_CH2;
		}break;
		
		case 3:
		{
			timerChannel = TIMER_CH_3;
			interruptSource = TIMER_INT_CH3;
			interruptFlag = TIMER_INT_FLAG_CH3;
		}break;		
	}
	/* clear interrupt bit */
    timer_interrupt_flag_clear(cfg->timerPeriph,interruptFlag);	
	timer_interrupt_disable(cfg->timerPeriph, interruptSource);	
}

void timerStart(tsCfgTimer *cfg)
{
	timer_enable(cfg->timerPeriph); 
}

void timerStop(tsCfgTimer *cfg)
{
	timer_disable(cfg->timerPeriph); 
}